<script setup lang="ts">
import { ChromeFilled, Edit, UploadFilled, MagicStick } from '@element-plus/icons-vue'
import JsonView from 'vue-json-viewer'
import useDragramStore from '../../store/useDragramStore'
import type { InputInstance } from 'element-plus/es/components/input/index.mjs'
import { v4 as uuid } from 'uuid'

const model = defineModel<boolean>()

const loading = ref(false)
const activeStep = ref(0)
const CurlInputRef = ref<InputInstance>()
const startParse = async () => {
  if (!curlText.value || curlText.value.indexOf('curl') === -1) {
    CurlInputRef.value?.focus()
    return
  }
  loading.value = true
  await parseCurl()
  await sleep(666)
  activeStep.value++
  await parseTableColumns()
  await parseSearchParams()
  activeStep.value++
  loading.value = false
}

const curlText = ref('')
const httpRes = ref<any>('')
const httpReq = ref<any>('')
const tableRowData = ref<tableRowData[]>([
  // { id: 'row-1', prop: ['key1'], title: '未知字段', show: true },
  // { id: 'row-2', prop: ['key2'], title: '未知字段', show: true },
  // { id: 'row-3', prop: ['key3'], title: '未知字段', show: true }
])
const searchItems = ref<QueryItemType[]>([])
const parseCurl = async () => {
  const res = await $fetch<ResBodyType>('/api/common/parse_curl', {
    method: 'post',
    body: {
      curl: curlText.value
    }
  })
  console.log('res', res.body)
  httpRes.value = res.body.res
  httpReq.value = res.body.req
}

// 递归找到第一个数组类型 并且取出[0] 作为表格列数据
const parseTableColumns = async () => {
  const obj = httpRes.value
  findArray(obj)
}
function findArray(obj: any) {
  for (let key in obj) {
    // debugger
    if (Array.isArray(obj[key])) {
      const tablerow = useCloneDeep(obj[key][0])
      Object.entries(tablerow).forEach(([key, value], index) => {
        tableRowData.value.push({
          id: uuid(),
          prop: [key],
          title: typeof value === 'string' && value ? value : '未知字段',
          show: true
        })
      })
    } else if (typeof obj[key] === 'object') {
      findArray(obj[key])
    }
  }
}

// 解析查询参数
// 屏蔽分页key
const disKeys = ['pageNum', 'pageSize', 'pageIndex']
const parseSearchParams = () => {
  Object.keys(httpReq.value).forEach((key) => {
    if (!disKeys.includes(key)) {
      searchItems.value.push({
        type: 'input',
        name: '',
        modelKey: key,
        placeholder: '',
        show: true
      })
    }
  })
}

// const mock = ref([
//   {
//     prop: 'id',
//     title: 'id',
//     show: true
//   },
//   {
//     prop: 'title',
//     title: '国家',
//     show: true
//   }
// ])

// 聚焦 读取剪切板
const handleInputFocus = () => {
  navigator.clipboard
    .readText()
    .then((text) => {
      if (text.indexOf('curl') === -1) return
      curlText.value = text
    })
    .catch((err) => {})
}

const dragramStore = useDragramStore()
const submit = () => {
  if (tableRowData.value.length === 0) return
  dragramStore.addBatchColumns(tableRowData.value)
  dragramStore.addBatchSearchItems(searchItems.value)
  model.value = false
}

// 拖拽事件
let dragKeyItem = ref<tableRowData>()
const handleDragStart = (value: tableRowData) => {
  console.log('handleDragStart', value)
  dragKeyItem.value = value
}

const handleDragenter = (e: any) => {
  // console.log('handleDragenter', e.target.dataset.item)
}

// 拖到哪一行放下
const handleDrop = (e: any) => {
  console.log('handleDrop', e)

  if (e.target.dataset.item) {
    // 获取在哪一行放下
    const item = JSON.parse(e.target.dataset.item) as tableRowData
    console.log('handleDrop', item)
    if (item.id === dragKeyItem.value?.id) return
    // 把key放到该行之上
    const index = tableRowData.value.findIndex((v) => v.id === item.id)
    tableRowData.value[index].prop = tableRowData.value[index].prop.concat(
      dragKeyItem.value!.prop
    )

    // 删除被拖动的元素
    tableRowData.value = tableRowData.value.filter((v) => v.id !== dragKeyItem.value!.id)
  }
}

const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
}

const handleDragend = () => {
  dragKeyItem.value = undefined
}

// 双击查分合并行
const spiteRow = (value: tableRowData) => {
  if (value.prop.length > 1) {
    for (let index = 0; index < value.prop.length; index++) {
      if (index === 0) continue
      const prop = value.prop[index]
      tableRowData.value.push({
        id: uuid(),
        prop: [prop],
        title: '未知字段',
        show: true
      })
    }
    value.prop = [value.prop[0]]
  }
}
</script>

<template>
  <client-only>
    <el-drawer
      v-model="model"
      :show-close="false"
      title="HTTP请求自动渲染页面"
      size="60%"
    >
      <main>
        <el-input
          ref="CurlInputRef"
          v-model="curlText"
          type="textarea"
          :rows="10"
          class="curl-input"
          placeholder="请输入curl命令,系统将根据接口自动生成页面"
          @focus="handleInputFocus"
        ></el-input>
        <transition name="el-fade-in-linear">
          <el-card v-show="httpRes" shadow="never">
            <template #header>
              <h1 class="font-bold text-xl">2——解析http</h1>
            </template>
            <JsonView :value="httpRes" />
          </el-card>
        </transition>
        <transition name="el-fade-in-linear">
          <el-card v-show="tableRowData.length > 0">
            <template #header>
              <h1 class="font-bold text-xl">
                3——确认列表名称和绑定key
                <el-text size="small" type="danger">(拖动合并列)</el-text>
              </h1>
            </template>
            <section class="flex gap-3">
              <div class="flex-1">
                <h1 class="text-base font-medium">table列表</h1>
                <table class="column-show">
                  <thead>
                    <tr>
                      <td>绑定key</td>
                      <td>列名</td>
                      <td>操作</td>
                    </tr>
                  </thead>
                  <tbody>
                    <tr
                      class="cursor-move select-none"
                      :class="{ disable: !item.show }"
                      v-for="item in tableRowData"
                      :key="item.prop.join('-')"
                      :draggable="item.show"
                      @dragstart.stop="handleDragStart(item)"
                      @dragenter="handleDragenter"
                      @dragover="handleDragOver"
                      @drop.stop="handleDrop"
                      @dragend="handleDragend"
                      :data-item="JSON.stringify(item)"
                    >
                      <td @dblclick="spiteRow(item)">
                        <ul>
                          <li
                            v-for="key in item.prop"
                            :key="key"
                            :data-item="JSON.stringify(item)"
                          >
                            {{ key }}
                          </li>
                        </ul>
                        <!-- {{ item.prop }} -->
                      </td>
                      <td>
                        <el-input v-model="item.title" size="small"></el-input>
                      </td>
                      <td>
                        <el-button
                          size="small"
                          type="danger"
                          @click="item.show = !item.show"
                          >移除</el-button
                        >
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <div class="w-1/2">
                <h1 class="text-base font-medium">检索条件</h1>
                <table class="column-show">
                  <thead>
                    <tr>
                      <td>检索key</td>
                      <td>提示</td>
                      <td>操作</td>
                    </tr>
                  </thead>
                  <tbody>
                    <tr
                      :class="{ disable: !item.show }"
                      v-for="item in searchItems"
                      :key="item.modelKey"
                    >
                      <td>{{ item.modelKey }}</td>
                      <td>
                        <el-input v-model="item.name" size="small"></el-input>
                      </td>
                      <td>
                        <el-button
                          size="small"
                          type="danger"
                          @click="item.show = !item.show"
                          >移除</el-button
                        >
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </section>
          </el-card>
        </transition>
      </main>
      <footer class="mt-10">
        <div>
          <el-steps :active="activeStep" finish-status="success" simple>
            <el-step title="解析curl" :icon="Edit"></el-step>
            <el-step title="解析http" :icon="UploadFilled"></el-step>
            <el-step title="确认列表结构"></el-step>
          </el-steps>
        </div>
        <div class="text-center mt-5">
          <el-button
            v-show="activeStep === 0"
            type="success"
            size="large"
            :icon="ChromeFilled"
            :loading="loading"
            @click="startParse"
            >解析curl</el-button
          >
          <el-button
            v-show="activeStep === 2"
            type="success"
            size="large"
            :icon="MagicStick"
            @click="submit"
            >确认列表结构，开始渲染页面</el-button
          >
        </div>
      </footer>
    </el-drawer>
  </client-only>
</template>

<style lang="scss" scoped>
.curl-input {
  :deep(textarea) {
    &::-webkit-input-placeholder {
      font-size: 16px;
      font-weight: 500;
      color: var(--el-color-primary-light-5);
    }
  }
}
.column-show {
  border: 1px solid #000;
  td {
    border: 1px solid #000;
    padding: 6px 10px;
  }
  .disable {
    color: #ccc;
    text-decoration: line-through;
  }
}
</style>
